package com.chendx.store.goods.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.chendx.model.common.dtos.PageRequestDto;
import com.chendx.model.common.dtos.PageResponseResult;
import com.chendx.model.common.dtos.ResponseResult;
import com.chendx.model.common.enums.AppHttpCodeEnum;
import com.chendx.model.goods.dto.GoodsDto;
import com.chendx.model.goods.pojo.*;
import com.chendx.model.goods.vo.SpecialSku;
import com.chendx.store.common.constants.goods.GoodsConstants;
import com.chendx.store.goods.mapper.BrandMapper;
import com.chendx.store.goods.mapper.CategoryMapper;
import com.chendx.store.goods.service.GoodsService;
import com.chendx.store.goods.service.SkuService;
import com.chendx.store.goods.service.SpecialPerformanceService;
import com.chendx.store.goods.service.SpuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by chendx on 2022/4/18.
 */
@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private SpecialPerformanceService specialPerformanceService;
    @Autowired
    private SpuService spuService;
    @Autowired
    private SkuService skuService;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private BrandMapper brandMapper;

    @Override
    @Transactional
    public ResponseResult saveGoods(GoodsDto dto) {
        if (dto == null || dto.getSpu() == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Spu spu = dto.getSpu();
        spuService.save(spu);

        Category category = categoryMapper.selectById(spu.getCategory3Id());
        if (StringUtils.isEmpty(category)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        Brand brand = brandMapper.selectById(spu.getBrandId());
        if (StringUtils.isEmpty(brand)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (StringUtils.isEmpty(dto.getSkuList())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        List<Sku> skuList = dto.getSkuList();
        for (Sku sku : skuList){
            //构建SKU名称，采用SPU+规格值组装
            if(StringUtils.isEmpty(sku.getSpec())){
                sku.setSpec("{}");
            }
            //获取Spu的名字
            String name = spu.getName();
            //将规格转换成Map
            Map<String,String> specMap = JSON.parseObject(sku.getSpec(), Map.class);
            //循环组装Sku的名字
            for (Map.Entry<String, String> entry : specMap.entrySet()) {
                name+="  "+entry.getValue();
            }
            sku.setName(name);
            sku.setSn(spu.getSn());
            //SpuId
            sku.setSpuId(spu.getId());
            //创建日期
            sku.setCreateTime(new Date());
            //修改日期
            sku.setUpdateTime(new Date());
            //商品分类ID
            sku.setCategoryId(spu.getCategory3Id());
            //分类名字
            sku.setCategoryName(category.getName());
            //品牌名字
            sku.setBrandName(brand.getName());
            skuService.save(sku);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Override
    public ResponseResult loadHighData(PageRequestDto dto) {
        if (dto == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        dto.checkParam();
        List<Sku> result = new ArrayList<>();
        String specialStr = redisTemplate.boundValueOps(GoodsConstants.SPECIL_HIGH_QUALITY_REDIS_KEY).get();
        if (StringUtils.isEmpty(specialStr)){
            result = skuService.list(Wrappers.<Sku>lambdaQuery().eq(Sku::getStatus, "1"));
            if (result != null){
                result.sort((o1, o2) -> o2.getSaleNum().compareTo(o1.getSaleNum()));
                if (result.size() > 30){
                    result = result.subList(0,30);
                }
                String jsonString = JSON.toJSONString(result);
                redisTemplate.opsForValue().set(GoodsConstants.SPECIL_HIGH_QUALITY_REDIS_KEY,jsonString);
            }
        }else{
            result = JSON.parseArray(specialStr,Sku.class);
        }
        PageResponseResult responseResult = new PageResponseResult(dto.getSize(),dto.getPage(),result.size());
        responseResult.setData(result);
        return responseResult;
    }

    @Override
    public ResponseResult loadSpecialData() {
        List<SpecialPerformance> list =
                specialPerformanceService.list(Wrappers.<SpecialPerformance>lambdaQuery().eq(SpecialPerformance::getStatus, "0"));
        List<Long> ids = list.stream().map(x -> x.getId()).collect(Collectors.toList());
        List<SpecialSku> resultList = new ArrayList<>();
        if (ids != null){
            for (Long id : ids){
                String str = redisTemplate.boundValueOps(GoodsConstants.SPECIL_PERFORMANCE_REDIS_KEY + id).get();
                if (StringUtils.isEmpty(str)){
                    SpecialSku specialSku = new SpecialSku();
                    SpecialPerformance specialPerformance
                            = list.stream().filter(x -> x.getId().equals(id)).collect(Collectors.toList()).get(0);
                    specialSku.setSpecialTitle(specialPerformance.getTitle());
                    specialSku.setSpecialImage(specialPerformance.getImages());
                    specialSku.setTitleImages(specialPerformance.getTitleImages());
                    String[] categoryIds = specialPerformance.getCategoryIds().split(",");
                    List<Sku> skuList = skuService.list(Wrappers.<Sku>lambdaQuery()
                            .in(Sku::getCategoryId, categoryIds));
                    skuList.sort((o1, o2) -> o2.getSaleNum().compareTo(o1.getSaleNum()));
                    if (skuList.size() > 30){
                        skuList = skuList.subList(0,30);
                    }
                    specialSku.setSkuList(skuList);
                    redisTemplate.opsForValue().set(GoodsConstants.SPECIL_PERFORMANCE_REDIS_KEY + id,JSON.toJSONString(specialSku));
                    resultList.add(specialSku);
                }else{
                    SpecialSku specialSku = JSON.parseObject(str, SpecialSku.class);
                    resultList.add(specialSku);
                }
            }
        }
        return ResponseResult.okResult(resultList);
    }
}
